#include <iostream>
#include <thread>
#include <chrono>
#include <condition_variable>
#include <queue>
#include <mutex>
#include <functional>

class Timer {
public:
    Timer(unsigned int interval_ms) :
            interval_ms_(interval_ms), count_(0), stop_(false) {}

    void start() {
        std::thread timer_thread(&Timer::timer_func, this);
        timer_thread.detach();
    }

    void stop() {
        stop_ = true;
    }

    void set_interval(unsigned int interval_ms) {
        interval_ms_ = interval_ms;
    }

    unsigned int get_count() const {
        return count_;
    }

    typedef std::function<void()> Action;
    void on_timer(Action action) {
        action_ = action;
    }

private:
    unsigned int interval_ms_;
    unsigned int count_;
    bool stop_;
    Action action_;

    std::queue<Action> queue_;
    std::mutex queue_mutex_;
    std::condition_variable queue_cv_;

    void timer_func() {
        while (!stop_) {
            std::unique_lock<std::mutex> lock(queue_mutex_);
            queue_cv_.wait_for(lock, std::chrono::milliseconds(interval_ms_));
            ++count_;
            if (action_) {
                action_();
            }
        }
    }
};

int main() {
    Timer timer(1000);
    timer.on_timer([] {
        std::cout << "Time is up!" << std::endl;
    });
    timer.start();

    std::this_thread::sleep_for(std::chrono::seconds(5));
    timer.stop();

    std::cout << "Timer count: " << timer.get_count() << std::endl;

    return 0;
}